<template>
    <el-row class="block">
        <div style="width:350px" class="devInfo mini-form">
            <el-form label-width="100px" size="mini">
                <el-form-item label="" class="mt5">
                    <el-button type="primary" @click="getDeviceList" size="mini">更新设备列表</el-button>
                </el-form-item>
                <el-form-item label="设备" class="mt5">
                    <exSelect v-model="device" label="" :dictList="deviceList" size="mini" elstyle="width:170px" @change="changeDev"></exSelect>
                    <el-button type="primary" @click="getDeviceInfo" size="mini">刷新</el-button>
                </el-form-item>
                <el-form-item label="图形检测" class="mt5">
                    <el-button type="primary" @click="cvTest" size="mini">查找图形</el-button>
                </el-form-item>
                <el-form-item label="连接状态" class="mt5">
                    {{statusMap[connectStatus]}}
                </el-form-item>
                <devBasePanel :devInfo="devInfo"></devBasePanel>
            </el-form>
            
        </div>
        <div style="width:320px" class="devImg pt20">
            <div :style="imgStyle" style="border: 0px red solid;margin:auto;position:relative;box-shadow: 5px 5px 25px #888888;">
                <div v-if="connectStatus==1 && devInfo.clickX>0" class="leftpoint" style="position:absolute;width:4px;height:4px;border-radius:4px;background:red;z-index:11;pointer-events: none;" 
                    :style="{top:(devInfo.clickY)+'px',left:(devInfo.clickX)+'px'}"></div>
                <div v-if="connectStatus==1 && devInfo.clickRX>0" style="position:absolute;width:4px;height:4px;border-radius:4px;background:blue;z-index:10;pointer-events: none;" 
                    :style="{top:(devInfo.clickRY)+'px',left:(devInfo.clickRX)+'px'}"></div>
                <canvas id="canvasEl" ref="canvasEl" :style="imgStyle" v-if="isShowCanvas"  @contextmenu="setRightClickPoint"></canvas>
            </div>
        </div>
        <div style="min-width:950px;padding-right:20px" class="pl10 pt10">
            <cmdPanel :devInfo="devInfo" :isBatch="this.isBatch" :defCfg="cfg"></cmdPanel>
        </div>
    </el-row>
</template>


<script>

import devBasePanel from "./comp/devBasePanel"
import cmdPanel from "./comp/cmdPanel"

export default {
    head() {
        return {
            script: [
                {
                    src:'/opencvjs/opencv.js',
                    type: 'text/javascript',
                }
            ],
        }
    },
    components:{
        devBasePanel,
        cmdPanel
    },
    props:{
        isBatch:{default:false},
        cfg: {},
    },
    watch:{
    },
    data() {
        return {
            rndId: parseInt(Math.random()*10000000),
            isShowCanvas : true,
            device:"",
            deviceList:[],
            connectStatus: 0,
            statusMap:{
                0: "未连接",
                1: "已连接",
                2: "连接失败",
            },
            devInfo:{
                aotoQry : false,
                asyncClick: false,
                asyncRecordCmd : false,
                devWidth: 0,
                devHeight: 0,
                devBet : 0,
                clickX : 0,
                clickY : 0,
                color : [],
                clickRX : 0,
                clickRY : 0,
                rcolor : [],
                colors : [],
                rectcolors : [],
                rectcolorswidth: 1,
                rectcolorsheight: 1,
                curApp : "",
                curAppRnd : "",
                curImg : "",
            },
        };
    },
     

    mounted() {
        this.devInfoBak = JSON.stringify(this.devInfo)
        this.regIpc();
        this.getDeviceList()
    },
    computed:{
        showWidth(){
            var width = 300;
            return width;
        },
        showHeight(){
            var height = 400;
            if(this.devInfo.devWidth!=0){
                this.devInfo.devBet = this.devInfo.devWidth/this.showWidth;
                height = this.devInfo.devHeight /this.devInfo.devBet;
            }
            return height;
        },
        imgStyle(){
            return `height: ${this.showHeight}px;width:${this.showWidth}px;`;
        },
    },
    provide () {
      return {
        doDevCmd: this.doDevCmd,
        doDevClick : this.doDevClick,
        getImgData : this.getImgData,
        getImageData : this.getImageData,
        getDevPic : this.getDevPic,
        getCurApp : this.getCurApp,
        doDevKeyEvent: this.doDevKeyEvent,
        updateScreen : this.updateScreen
      }
    },
    inject:["sendWsMsg"],

    methods: {
        cvTest(){
            var that = this;
            
            var wholeImg = that.canvasCtx.getImageData(0, 0, this.showWidth, this.showHeight);
            var rectwidth = that.devInfo.clickRX-that.devInfo.clickX;
            var rectheight = that.devInfo.clickRY-that.devInfo.clickY;
            if(rectwidth<1 || rectheight<1) return;
            var rectImg = that.canvasCtx.getImageData(that.devInfo.clickX,that.devInfo.clickY,
                rectwidth,rectheight)
            // var rectImg = that.canvasCtx.getImageData(100, 100, 100, 100);
            var src = cv.matFromImageData(wholeImg)
            var templ = cv.matFromImageData(rectImg)
            
            let dst = new cv.Mat();
            let mask = new cv.Mat();
            //参数四：SQDIFF和SQDIFF_NORMED越小数值匹配效果更好，其他方法则反之
            // methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',  
            //    'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']  

            for(var i=0;i<10;i++){
                cv.matchTemplate(src, templ, dst, cv.TM_CCOEFF_NORMED, mask);
                let result = cv.minMaxLoc(dst, mask);
                console.log(result)
                if(result.maxVal<0.75){
                    break;
                }
                // if(result.maxVal<1000000){
                //     break;
                // }
                let maxPoint = result.maxLoc;
                let color = new cv.Scalar(255, 0, 0, 255);
                let point = new cv.Point(maxPoint.x + templ.cols, maxPoint.y + templ.rows);
                cv.rectangle(src, maxPoint, point, color, -1, cv.LINE_AA, 0);
            }

            
            // let minPoint = result.minLoc;
            // let color1 = new cv.Scalar(0, 0, 255, 255);
            // let point1 = new cv.Point(minPoint.x + templ.cols, minPoint.y + templ.rows);
            // cv.rectangle(src, minPoint, point1, color1, 2, cv.LINE_8, 0);


            cv.imshow('canvasEl', src);
            src.delete(); dst.delete(); mask.delete();

        },
        setClickPoint(e,color){
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            this.devInfo.color = color || [];
            this.devInfo.clickX = e.layerX; 
            this.devInfo.clickY = e.layerY; 
            if(this.devInfo.asyncRecordCmd){
                this.selGroupInfo.cmds.push({"type":"click","appPath":"","x1":this.devInfo.clickX,"y1":this.devInfo.clickY,"x2":0,"y2":0})
            }
            if(this.devInfo.asyncClick){
                this.doDevClick(this.devInfo.clickX,this.devInfo.clickY);
            }
        },
        setRightClickPoint(e,isNew,color){
            if(!isNew) return;
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            this.devInfo.rcolor = color || [];
            this.devInfo.clickRX = e.layerX; 
            this.devInfo.clickRY = e.layerY; 
            if(this.devInfo.asyncRecordCmd){
                this.selGroupInfo.cmds.push({"type":"click","appPath":"","x1":this.devInfo.clickRX,"y1":this.devInfo.clickRY,"x2":0,"y2":0})
            }
        },
        initCanvas(){
            var that = this;
            var el = this.$refs.canvasEl;
            el.height = that.showHeight;
            if(!el) return;
            var ctx = el.getContext('2d');
            ctx.strokeStyle = '#BADA55'; //ctx is the canvas
            ctx.lineJoin = 'round';
            ctx.lineCap = 'round';
            ctx.lineWidth = 1;
            that.canvasCtx =ctx;
            let isDrawing = false;
            var lineMap={
                x1:0,
                y1:0,
                c1:[],
                x2:0,
                y2:0,
                c2:[]
            }
            function draw(e) {
                if(Math.abs(lineMap.x1-lineMap.x2)<5 && Math.abs(lineMap.y1-lineMap.y2)<5){
                    if(e.button==0){
                        that.setClickPoint(e,lineMap.c1);
                    }else{
                        that.setRightClickPoint(e,true,lineMap.c2);
                    }
                    return;
                }
                that.$nextTick(()=>{
                    that.devInfo.clickX = lineMap.x1;
                    that.devInfo.clickY = lineMap.y1;
                    that.devInfo.color = lineMap.c1;
                    that.devInfo.clickRX = lineMap.x2;
                    that.devInfo.clickRY = lineMap.y2;
                    that.devInfo.rcolor = lineMap.c2;
                    var colorData = that.getImgData(lineMap.x1,lineMap.y1,lineMap.x2-lineMap.x1,lineMap.y2-lineMap.y1)
                    that.devInfo.colors = colorData || [];
                    if(that.devInfo.asyncRecordCmd){
                        that.selGroupInfo.cmds.push({"type":"move","appPath":"",
                            "x1":that.devInfo.clickX,"y1":that.devInfo.clickY,"x2":that.devInfo.clickRX,"y2":that.devInfo.clickRY})
                    }

                    // setTimeout(()=>{
                    //     ctx.beginPath();
                    //     // start from
                    //     ctx.moveTo(lineMap.x1, lineMap.y1);
                    //     // go to
                    //     ctx.lineTo(lineMap.x2, lineMap.y2);
                    //     ctx.stroke();
                    // },300)
                })
                
            }
            el.addEventListener('mousedown', (e) => {
                var colorData = this.getImgData(e.offsetX,e.offsetY)
                lineMap={
                    x1:e.offsetX,
                    y1:e.offsetY,
                    c1:colorData,
                    x2:0,
                    y2:0
                }
            });
            // el.addEventListener('mousemove', draw);
            el.addEventListener('mouseup', (e) => {
                var colorData = this.getImgData(e.offsetX,e.offsetY)
                lineMap.x2=e.offsetX;
                lineMap.y2=e.offsetY;
                lineMap.c2=colorData;
                draw(e)
            });
            el.addEventListener('mouseout', () => isDrawing = false);
        },
        getImageData(x,y,width,height){
            var rectimgData = this.canvasCtx.getImageData(x,y,width,height);
            return rectimgData;
        },
        getImgData(x,y,width=1,height=1,getRect){
            var that = this;
            if(height<1) height = 1;
            if(width==0) return [];
            var imgData = that.canvasCtx.getImageData(x,y,width,1).data;
            var colorData = [];
            if(width==1){
                colorData = [imgData[0],imgData[1],imgData[2]];
            }else{
                if(getRect){
                    var rectcolors = []
                    var rectimgData = that.canvasCtx.getImageData(x,y,width,height).data;
                    that.devInfo.rectcolorswidth = width;
                    that.devInfo.rectcolorsheight = height;
                    var subarr = [];
                    rectimgData.map((item,idx)=>{
                        var mod = idx%4;
                        if(mod==0){
                            subarr = [];
                            subarr.push(item)
                        }else if(mod==1){
                            subarr.push(item)
                        }else if(mod==2){
                            subarr.push(item)
                        }else if(mod==3){
                            rectcolors.push(subarr)
                        }
                    })
                    that.devInfo.rectcolors = rectcolors;
                    return {
                        rectWidth : width,
                        rectHeight : height,
                        rectcolors : rectcolors,
                    };
                }
                var imgData = that.canvasCtx.getImageData(x,y,width,1).data;
                var subarr = [];
                imgData.map((item,idx)=>{
                    var mod = idx%4;
                    if(mod==0){
                        subarr = [];
                        subarr.push(item)
                    }else if(mod==1){
                        subarr.push(item)
                    }else if(mod==2){
                        subarr.push(item)
                    }else if(mod==3){
                        colorData.push(subarr)
                    }
                })
            }
            return colorData;
        },
        updateScreen(){
            var that =this;
            if(!this.canvasCtx){
                this.initCanvas();
            }
            var msg = {
                code: "getScreen",
                rndId : this.rndId,
                param: {
                    name : this.device
                }
            }
            var cb = (res)=>{
                if(res.isSucc){
                    var img = new Image();
                    img.src=res.data;
                    img.onload = ()=>{
                        img.width = that.showWidth;
                        img.height = that.showHeight;
                        that.canvasCtx.drawImage(img,0,0,that.showWidth,that.showHeight)
                        that.canvasCtx.save();
                        that.devInfo.curImg = Math.random();
                    }
                }else{
                    this.$message.error("获取设备屏幕画面失败:"+res.message)
                }
            }
            this.sendWsMsg(msg,cb)
            return;
            this.random = Math.random();
            var src = `/img/screenshot.png?name=${this.device}&rnd=${this.random}`;
            // ctx.setTransform(1, 0, 0, 1, 0, 0);
			var img = new Image();
			img.onload = ()=>{
                img.width = that.showWidth;
                img.height = that.showHeight;
                that.canvasCtx.drawImage(img,0,0,that.showWidth,that.showHeight)
                that.canvasCtx.save();
                that.devInfo.curImg = Math.random();
			}
			img.src = src;
        },
        updateScreenBak(){
            var that =this;
            this.random = Math.random();
            var src = `/img/screenshot.png?name=${this.device}&rnd=${this.random}`;
            if(!this.canvasCtx){
                this.initCanvas();
            }
            // ctx.setTransform(1, 0, 0, 1, 0, 0);
			var img = new Image();
			img.onload = ()=>{
                img.width = that.showWidth;
                img.height = that.showHeight;
                that.canvasCtx.drawImage(img,0,0,that.showWidth,that.showHeight)
                that.canvasCtx.save();
                that.devInfo.curImg = Math.random();
			}
			img.src = src;
        },
        changeDev(){
            var tmp =JSON.parse(this.devInfoBak)
            Object.assign(this.devInfo,tmp)
            this.connectStatus = 0;
            if(this.device) this.getDeviceInfo();
        },
        getDeviceList(){
            this.device = "";
            this.deviceList = [];
            electron.ipcRenderer.send("doCmd",{name:"getDeviceList"+this.rndId,cmd:"adb devices",param:{type:"adb"}})
        },
        getDeviceInfo(){
            this.devInfo.devWidth = 0;
            this.devInfo.devHeight = 0;
            this.connectStatus = 0;
            if(!this.device){
                this.$message.error("请先选择设备")
                return;
            }
            electron.ipcRenderer.send("doCmd",{name:"getWindowInfo"+this.rndId,cmd:"adb shell dumpsys window displays",param:{type:"adb",devname:this.device}})
        },
        getCurApp(){
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            electron.ipcRenderer.send("doCmd",{name:"getCurApp"+this.rndId,cmd:"adb shell dumpsys window",param:{type:"adb",devname:this.device}})
        
        },
        getDevPic(){
            var curtime = new Date().getTime();
            this.preGetPicTime = this.preGetPicTime || 0;
            if(curtime-this.preGetPicTime<1000){
                return;
            }
            this.preGetPicTime = curtime;
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            electron.ipcRenderer.send("doCmd",{name:"getDevPic"+this.rndId,cmd:`adb shell /system/bin/screencap -p /sdcard/${this.device}.png&adb pull /sdcard/${this.device}.png D:/tmp/${this.device}.png`,param:{type:"adb",devname:this.device}})
        },
        doDevClick(clickX,clickY){
            if(!clickX || !clickY) return;
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            electron.ipcRenderer.send("doCmd",{name:"doDevCmd"+this.rndId,cmd:`adb shell input tap ${clickX*this.devInfo.devBet} ${clickY*this.devInfo.devBet} `,param:{type:"adb",devname:this.device}})
            setTimeout(()=>{
                this.getDevPic();
            },500)
        },
        doDevCmd(cmd){
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            console.log("cmd: "+cmd)
            electron.ipcRenderer.send("doCmd",{name:"doDevCmd"+this.rndId,cmd:cmd,param:{type:"adb",devname:this.device}})
        },
        doDevKeyEvent(key){
            if(this.connectStatus!=1) return;
            if(!this.device) return;
            if(!key) return;
            electron.ipcRenderer.send("doCmd",{name:"doDevCmd"+this.rndId,cmd:`adb shell input keyevent ${key}`,param:{type:"adb",devname:this.device}})
            setTimeout(()=>{
                this.getDevPic();
            },500)
        },
        regIpc(){
            var that = this;
            if(!window.electron){
                return;
            }
            electron.ipcRenderer.send("doCmd",{name:"createDir",cmd:"md d:\\tmp"})
            this.registerListen(this,"getWindowInfo"+this.rndId,(res)=>{
                try{
                    if(res.isSucc){
                        // that.$message.info(res.info);
                        var info = res.info.match(/cur=[0-9]*x[0-9]*/)
                        if(!info || info.length==0) return;
                        var arr = info[0].split(/=|x/);
                        that.connectStatus = 1;
                        that.devInfo.devWidth = arr[1];
                        that.devInfo.devHeight = arr[2];
                        // that.isShowCanvas = false;
                        that.$nextTick(()=>{
                            // that.isShowCanvas = true;
                            that.getDevPic();
                            that.getCurApp();
                            that.canvasCtx = null;
                            that.initCanvas();
                        })
                    }else{
                        that.connectStatus = 2;
                        that.$message.error("指令("+res.cmd+")执行异常:"+res.info)
                    }
                }catch(ex){
                    that.$message.error("指令执行异常:"+ex.message)
                }
            });
            this.registerListen(this,"getCurApp"+this.rndId,(res)=>{
                try{
                    if(res.isSucc){
                        var pos = res.info.indexOf("mCurrentFocus");
                        if(pos!=-1){
                            var tmparr = res.info.match(/mCurrentFocus.*[}]/)
                            if(tmparr && tmparr.length>0){
                                tmparr = tmparr[0];
                                tmparr = tmparr.split(" ");
                                tmparr = tmparr[tmparr.length-1];
                                tmparr = tmparr.substring(0,tmparr.length-1);
                                that.devInfo.curApp = tmparr;
                                that.devInfo.curAppRnd = Math.random()
                            }
                        }
                    }else{
                        that.$message.error("指令("+res.cmd+")执行异常:"+res.info)
                    }
                }catch(ex){
                    that.$message.error("指令执行异常:"+ex.message)
                }
            });
            this.registerListen(this,"getDevPic"+this.rndId,(res)=>{
                try{
                    if(res.isSucc){
                        that.updateScreen();
                    }else{
                        that.$message.error("指令("+res.cmd+")执行异常:"+res.info)
                    }
                }catch(ex){
                    that.$message.error("指令执行异常:"+ex.message)
                }
            });
            this.registerListen(this,"doDevCmd"+this.rndId,(res)=>{
                try{
                    if(!res.isSucc) that.$message.error("指令("+res.cmd+")执行异常:"+res.info)
                }catch(ex){
                    that.$message.error("指令执行异常:"+ex.message)
                }
            });
            
            this.registerListen(this,"getDeviceList"+this.rndId,(res)=>{
                try{
                    if(res.isSucc){
                        // that.$message.info(res.info);
                        console.info(res.info);
                        res.info=res.info.replace(/\\r/g,"");
                        that.deviceList = [];
                        that.device = "";
                        var lines = res.info.split("\n");
                        lines.map(row=>{
                            var item = {};
                            var arr = row.split("\t");
                            if(arr.length!=2) return;
                            if(row.match(/^.*device/)){
                                item={name:arr[0],value:arr[0],isAuth:true};
                            }else if(row.match(/^.*unauthorized/)){
                                item={name:arr[0]+"(请在手机授权)",value:arr[0],isAuth:false};
                            }
                            if(item.value){
                                that.deviceList.push(item);
                                if(!that.device && item.isAuth) that.device = item.value;
                                // if(that.devices.length==0) that.devices.push(item.value)
                            }
                        })
                        if(that.device){
                            that.getDeviceInfo()
                        }
                    }else{
                        that.$message.error("指令("+res.cmd+")执行异常:"+res.info)
                    }
                }catch(ex){
                    that.$message.error("指令执行异常:"+ex.message)
                }
            });
        },
    }
}
</script>

<style lang="less" scoped>

.block{
    min-height: 400px;
    width: 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: true;
    // border: 1px red solid;

    .devInfo{
        border-right: 1px gray dotted;
        height:100%;
    }
    .devImg{
        text-align: center;
        border-right: 1px gray dotted;
        // background: lightblue;
    }
}

.leftpoint{
    animation:change 1s linear 0s infinite;
}
@keyframes change{
    0% {background:#333;}
    25%{background:#ff0;}
    50%{background:#fff;}
    75%{background:#cf0;}
    100% {background:#f00;}}

</style>
